/**
 * 注册和获取局部状态
 */

import type { InjectionKey } from 'vue'
import { provide, inject } from 'vue'

import type { TAnyObject } from '../types/type'

// 用 Symbol 做标记，避免重名冲突
const flag = Symbol('__nf-state__') as InjectionKey<string>

/**
 * 注册和获取局部状态，基于 依赖注入 封装
 * @param state 状态，对象、reactive。不支持基础类型
 * @returns reg、get
 * @example 
 * 迭代：const [ regXXX, getXXX ] = defineState(state)
 * 解构：const { reg, get } = defineState(state)
 * 别名：const { reg: regXXX, get: getXXX } = defineState(state)
 */
export default function defineState<T extends TAnyObject>(state: T) {
  /**
   * 注入一个状态，供子组件使用
   * @returns 状态 
   */
  function reg() {
    // 注入一个状态，供子组件使用
    provide<T>(flag, state)
    return state
  }

  /**
   * 获取父组件注入的状态
   * @returns 状态
   */
  function get() {
    // 获取父组件注入的状态
    const re = inject<T>(flag)
    if (re) {
      return re
    } else {
      console.error(`没有找到局部状态：${flag.toString()}`)
      return {} as T
      // throw new Error('未注册')
    }
  }

  // 迭代器
  const res = {
    reg,
    get,
    [Symbol.iterator]: () => {
      let i = 0
      return {
        next() {
          if (i < 2) {
            return { value: i++ ? get : reg, done: false }
          } else {
            return { value: reg, done: true }
          }
        }
      }
    }
  }
  
  return res

}